/*******************************************************************************
 * Copyright (c) 2008, 2009 Tapestry IDE Developers
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Tapestry IDE Developers - initial API and implementation
 *******************************************************************************/
package com.googlecode.tapestry.ide.internal.core.ioc;

import org.eclipse.core.runtime.ILog;

import com.googlecode.tapestry.ide.TapestryPlugin;
import com.googlecode.tapestry.ide.core.ioc.IBeanFactory;
import com.googlecode.tapestry.ide.core.model.ITapestryModel;
import com.googlecode.tapestry.ide.internal.core.model.TapestryModel;
import com.googlecode.tapestry.ide.internal.ui.TapestryLabelDecorator;
import com.googlecode.tapestry.ide.internal.ui.actions.ToggleNatureAction;
import com.googlecode.tapestry.ide.internal.ui.navigator.ProjectExplorerContentProvider;
import com.googlecode.tapestry.ide.internal.ui.navigator.ProjectExplorerLabelProvider;
import com.googlecode.tapestry.ide.ui.ImageDescriptorRegistry;

/**
 * The Class SimpleBeanFactoryAdapter.
 */
public class SimpleBeanFactoryAdapter implements IBeanFactoryAdapter {

	/** The image descriptor registry. */
	private volatile ImageDescriptorRegistry imageDescriptorRegistry;

	/** The tapestry model. */
	private volatile TapestryModel tapestryModel;

	/** The project explorer content provider. */
	private volatile ProjectExplorerContentProvider projectExplorerContentProvider;

	/** The project explorer label provider. */
	private volatile ProjectExplorerLabelProvider projectExplorerLabelProvider;

	/** The add nature action. */
	private volatile ToggleNatureAction addNatureAction;

	/** The remove nature action. */
	private volatile ToggleNatureAction removeNatureAction;

	/** The label decorator. */
	private volatile TapestryLabelDecorator labelDecorator;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.tapestry.ide.internal.core.ioc.IBeanFactoryAdapter#getBean
	 * (java.lang.String)
	 */
	@Override
	public Object getBean(String id) {
		if (IBeanFactory.LOG.equals(id)) {
			return getLog();
		}

		if (IBeanFactory.IMAGE_REGISTRY.equals(id)) {
			return TapestryPlugin.getDefault().getImageRegistry();
		}

		if (IBeanFactory.IMAGE_DESCRIPTOR_REGISTRY.equals(id)) {
			if (imageDescriptorRegistry == null) {
				synchronized (this) {
					if (imageDescriptorRegistry == null) {
						imageDescriptorRegistry = new ImageDescriptorRegistry();
					}
				}
			}
			return imageDescriptorRegistry;
		}

		if (IBeanFactory.TAPESTRY_MODEL.equals(id)) {
			return getTapestryModel();
		}

		if (IBeanFactory.PROJECT_EXPLORER_CONTENT_PROVIDER.equals(id)) {
			if (projectExplorerContentProvider == null) {
				synchronized (this) {
					if (projectExplorerContentProvider == null) {
						projectExplorerContentProvider = new ProjectExplorerContentProvider(
								getTapestryModel());
					}
				}
			}
			return projectExplorerContentProvider;
		}

		if (IBeanFactory.PROJECT_EXPLORER_LABEL_PROVIDER.equals(id)) {
			if (projectExplorerLabelProvider == null) {
				synchronized (this) {
					if (projectExplorerLabelProvider == null) {
						projectExplorerLabelProvider = new ProjectExplorerLabelProvider();
					}
				}
			}
			return projectExplorerLabelProvider;
		}

		if (IBeanFactory.ADD_NATURE_ACTION.equals(id)) {
			if (addNatureAction == null) {
				synchronized (this) {
					if (addNatureAction == null) {
						addNatureAction = new ToggleNatureAction();
					}
				}
			}
			return addNatureAction;
		}

		if (IBeanFactory.REMOVE_NATURE_ACTION.equals(id)) {
			if (removeNatureAction == null) {
				synchronized (this) {
					if (removeNatureAction == null) {
						removeNatureAction = new ToggleNatureAction();
					}
				}
			}
			return removeNatureAction;
		}

		if (IBeanFactory.LABEL_DECORATOR.equals(id)) {
			if (labelDecorator == null) {
				synchronized (this) {
					if (labelDecorator == null) {
						labelDecorator = new TapestryLabelDecorator(
								getTapestryModel());
					}
				}
			}
			return labelDecorator;
		}

		return null;
	}

	/**
	 * Gets the tapestry model.
	 * 
	 * @return the tapestry model
	 */
	ITapestryModel getTapestryModel() {
		if (tapestryModel == null) {
			synchronized (this) {
				if (tapestryModel == null) {
					tapestryModel = new TapestryModel();
					tapestryModel.startup();
				}
			}
		}
		return tapestryModel;
	}

	/**
	 * Gets the log.
	 * 
	 * @return the log
	 */
	ILog getLog() {
		return TapestryPlugin.getDefault().getLog();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.tapestry.ide.internal.core.ioc.IBeanFactoryAdapter#shutdown
	 * ()
	 */
	@Override
	public void shutdown() {
		if (tapestryModel != null) {
			tapestryModel.shutdown();
		}
	}

}
